home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_300 / 330_03 / tskpip.c < prev    next >
C/C++ Source or Header  |  1990-10-10  |  6KB  |  282 lines

  1. /*
  2.    --- Version 2.2 90-10-12 10:33 ---
  3.  
  4.    TSKPIP.C - CTask - Pipe handling routines.
  5.  
  6.    Public Domain Software written by
  7.       Thomas Wagner
  8.       Ferrari electronic Gmbh
  9.       Beusselstrasse 27
  10.       D-1000 Berlin 21
  11.       Germany
  12. */
  13.  
  14. #include "tsk.h"
  15. #include "tsklocal.h"
  16.  
  17. /*
  18.    create_pipe - initialises pipe.
  19. */
  20.  
  21. pipeptr Globalfunc create_pipe (pipeptr pip, farptr buf, word bufsize
  22.                                 TN(byteptr name))
  23. {
  24. #if (TSK_DYNAMIC)
  25.    if (pip == LNULL)
  26.       {
  27.       if ((pip = tsk_palloc (sizeof (pipe))) == LNULL)
  28.          return LNULL;
  29.       pip->flags = F_TEMP;
  30.       }
  31.    else
  32.       pip->flags = 0;
  33.    if (buf == LNULL)
  34.       {
  35.       if ((buf = tsk_palloc (bufsize)) == LNULL)
  36.          {
  37.          if (pip->flags & F_TEMP)
  38.             tsk_pfree (pip);
  39.          return LNULL;
  40.          }
  41.       pip->flags |= F_STTEMP;
  42.       }
  43. #endif
  44.  
  45.    tsk_init_qhead (&pip->wait_read, TYP_PIPE);
  46.    tsk_init_qhead (&pip->wait_write, TYP_PIPE);
  47.    tsk_init_qhead (&pip->wait_clear, TYP_PIPE);
  48.    pip->outptr = pip->inptr = pip->filled = 0;
  49.    pip->bufsize = bufsize;
  50.    pip->contents = (byteptr)buf;
  51.  
  52. #if (TSK_NAMED)
  53.    tsk_add_name (&pip->name, name, TYP_PIPE, pip);
  54. #endif
  55.  
  56.    return pip;
  57. }
  58.  
  59.  
  60. /*
  61.    delete_pipe - kills all processes waiting for reading from or writing
  62.                  to the pipe.
  63. */
  64.  
  65. void Globalfunc delete_pipe (pipeptr pip)
  66. {
  67.    CRITICAL;
  68.  
  69.    CHECK_EVTPTR (pip, TYP_PIPE, "Delete Pipe");
  70.  
  71.    C_ENTER;
  72.    tsk_kill_queue (&(pip->wait_read));
  73.    tsk_kill_queue (&(pip->wait_write));
  74.    tsk_kill_queue (&(pip->wait_clear));
  75.    pip->outptr = pip->inptr = pip->filled = 0;
  76.    C_LEAVE;
  77.  
  78. #if (TSK_NAMED)
  79.    tsk_del_name (&pip->name);
  80. #endif
  81.  
  82. #if (TSK_DYNAMIC)
  83.    if (pip->flags & F_STTEMP)
  84.       tsk_pfree (pip->contents);
  85.    if (pip->flags & F_TEMP)
  86.       tsk_pfree (pip);
  87. #endif
  88. }
  89.  
  90.  
  91. /*
  92.    read_pipe - Wait until a character is written to the pipe. If there 
  93.                is a character in the pipe on entry, it is assigned to 
  94.                the caller, and the task continues to run. If there are
  95.                tasks waiting to write, the first task is made eligible,
  96.                and the character is inserted into the pipe.
  97. */
  98.  
  99. int Globalfunc read_pipe (pipeptr pip, dword timeout)
  100. {
  101.    tcbptr curr;
  102.    int res;
  103.    CRITICAL;
  104.  
  105.    CHECK_EVTPTR (pip, TYP_PIPE, "Read Pipe");
  106.  
  107.    C_ENTER;
  108.  
  109.    if (pip->filled)
  110.       {
  111.       res = pip->contents [pip->outptr++];
  112.       if (pip->outptr >= pip->bufsize)
  113.          pip->outptr = 0;
  114.       pip->filled--;
  115.  
  116.       if (!((curr = (tcbptr)pip->wait_write.first)->cqueue.kind & Q_HEAD))
  117.          {
  118.          pip->contents [pip->inptr++] = (byte)curr->retsize;
  119.          if (pip->inptr >= pip->bufsize)
  120.             pip->inptr = 0;
  121.          pip->filled++;
  122.          tsk_runable (curr);
  123.          curr->retptr = LNULL;
  124.          }
  125.       else if (!pip->filled)
  126.          tsk_runable_all (&pip->wait_clear);
  127.  
  128.       C_LEAVE;
  129.       return res;
  130.       }
  131.  
  132.    tsk_wait (&pip->wait_read, timeout);
  133.    return (int)((dword)GLOBDATA current_task->retptr);
  134. }
  135.  
  136.  
  137. /*
  138.    c_read_pipe - If there is a character in the pipe on entry,
  139.                  read_pipe is called, otherwise en error status is returned.
  140. */
  141.  
  142. int Globalfunc c_read_pipe (pipeptr pip)
  143. {
  144.    CRITICAL, res;
  145.  
  146.    CHECK_EVTPTR (pip, TYP_PIPE, "Cond Read Pipe");
  147.  
  148.    C_ENTER;
  149.    res = (pip->filled) ? read_pipe (pip, 0L) : -1;
  150.    C_LEAVE;
  151.    return res;
  152. }
  153.  
  154.  
  155.  
  156. /*
  157.    write_pipe - Wait until space for the character to be written to the 
  158.                 pipe is available. If there is enough space in the pipe 
  159.                 on entry, the character is inserted into the pipe, and
  160.                 the task continues to run. If there are tasks waiting 
  161.                 to read, the first task is made eligible, and the character
  162.                 is passed to the waiting task.
  163. */
  164.  
  165. int Globalfunc write_pipe (pipeptr pip, byte ch, dword timeout)
  166. {
  167.    tcbptr curr;
  168.    CRITICAL;
  169.  
  170.    CHECK_EVTPTR (pip, TYP_PIPE, "Write Pipe");
  171.  
  172.    C_ENTER;
  173.  
  174.    if (pip->filled < pip->bufsize)
  175.       {
  176.       if (!((curr = (tcbptr)pip->wait_read.first)->cqueue.kind & Q_HEAD))
  177.          {
  178.          tsk_runable (curr);
  179.          curr->retptr = (farptr)ch;
  180.          C_LEAVE;
  181.          return 0;
  182.          }
  183.  
  184.       pip->contents [pip->inptr++] = ch;
  185.       if (pip->inptr >= pip->bufsize)
  186.          pip->inptr = 0;
  187.       pip->filled++;
  188.       C_LEAVE;
  189.       return 0;
  190.       }
  191.  
  192.    GLOBDATA current_task->retsize = ch;
  193.    tsk_wait (&pip->wait_write, timeout);
  194.    return (int)((dword)GLOBDATA current_task->retptr);
  195. }
  196.  
  197.  
  198. /*
  199.    c_write_pipe - If there is space for the character in the pipe on entry,
  200.                   write_pipe is called, otherwise en error status is returned.
  201. */
  202.  
  203. int Globalfunc c_write_pipe (pipeptr pip, byte ch)
  204. {
  205.    int res;
  206.    CRITICAL;
  207.  
  208.    CHECK_EVTPTR (pip, TYP_PIPE, "Cond Write Pipe");
  209.  
  210.    C_ENTER;
  211.    res = (pip->filled < pip->bufsize) ? write_pipe (pip, ch, 0L) : -1;
  212.    C_LEAVE;
  213.    return res;
  214. }
  215.  
  216.  
  217. /*
  218.    wait_pipe_empty - Wait until the pipe is empty. If the pipe is
  219.                      empty on entry, the task continues to run.
  220. */
  221.  
  222. int Globalfunc wait_pipe_empty (pipeptr pip, dword timeout)
  223. {
  224.    CRITICAL;
  225.  
  226.    CHECK_EVTPTR (pip, TYP_PIPE, "Wait Pipe Empty");
  227.  
  228.    C_ENTER;
  229.    if (!pip->filled)
  230.       {
  231.       C_LEAVE;
  232.       return 0;
  233.       }
  234.  
  235.    GLOBDATA current_task->retptr = LNULL;
  236.    tsk_wait (&pip->wait_clear, timeout);
  237.    return (int)((dword)GLOBDATA current_task->retptr);
  238. }
  239.  
  240.  
  241. /*
  242.    check_pipe - returns -1 if there are no characters in the pipe, else
  243.                 the first available character.
  244. */
  245.  
  246. int Globalfunc check_pipe (pipeptr pip)
  247. {
  248.    CHECK_EVTPTR (pip, TYP_PIPE, "Check Pipe");
  249.  
  250.    return (pip->filled) ? (int)pip->contents [pip->outptr] : -1;
  251. }
  252.  
  253.  
  254. /*
  255.    pipe_free - returns the number of free characters in the pipe.
  256. */
  257.  
  258. word Globalfunc pipe_free (pipeptr pip)
  259. {
  260.    CHECK_EVTPTR (pip, TYP_PIPE, "Pipe Free");
  261.    return pip->bufsize - pip->filled;
  262. }
  263.  
  264.  
  265. /*
  266.    flush_pipe - Empty the pipe buffer, activate tasks waiting for 
  267.                 pipe clear.
  268. */
  269.  
  270. void Globalfunc flush_pipe (pipeptr pip)
  271. {
  272.    CRITICAL;
  273.  
  274.    CHECK_EVTPTR (pip, TYP_PIPE, "Flush Pipe");
  275.    C_ENTER;
  276.    pip->inptr = pip->outptr = pip->filled = 0;
  277.  
  278.    tsk_runable_all (&pip->wait_clear);
  279.    C_LEAVE;
  280. }
  281.  
  282.